import { writeFile } from '@tauri-apps/plugin-fs';
import { tempDir, join } from '@tauri-apps/api/path';

/**
 * 图片处理工具类，提供通用的图片处理功能
 */
export class ImageProcessor {
  /**
   * 检查文件大小是否超过限制
   * @param file 要检查的文件
   * @param maxSizeBytes 最大允许的文件大小（字节），默认10MB
   * @returns 如果文件大小超出限制则抛出错误
   */
  static async checkFileSize(file: File, maxSizeBytes: number = 10 * 1024 * 1024): Promise<void> {
    if (file.size > maxSizeBytes) {
      throw new Error(`图片 ${file.name} 太大，请上传小于${(maxSizeBytes / 1024 / 1024).toFixed(0)}MB的图片`);
    }
  }

  /**
   * 压缩图片
   * @param file 要压缩的图片文件
   * @param maxWidth 最大宽度，默认1920
   * @param maxHeight 最大高度，默认1080
   * @param quality 压缩质量，默认0.8
   * @returns 压缩后的base64数据
   */
  static async compressImage(file: File, maxWidth = 1920, maxHeight = 1080, quality = 0.8): Promise<string> {
    return new Promise((resolve, reject) => {
      const img = new Image();
      
      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        if (!ctx) {
          reject(new Error('无法创建canvas上下文'));
          return;
        }
        
        let { width, height } = img;
        
        // 计算压缩比例，保持宽高比
        if (width > maxWidth || height > maxHeight) {
          const scale = Math.min(maxWidth / width, maxHeight / height);
          width = Math.round(width * scale);
          height = Math.round(height * scale);
        }
        
        // 设置canvas尺寸
        canvas.width = width;
        canvas.height = height;
        
        // 设置白色背景（解决透明背景问题）
        ctx.fillStyle = '#FFFFFF';
        ctx.fillRect(0, 0, width, height);
        
        // 绘制压缩后的图片
        ctx.drawImage(img, 0, 0, width, height);
        
        // 根据原文件类型选择输出格式
        const isPNG = file.type.toLowerCase().includes('png');
        const mimeType = isPNG ? 'image/png' : 'image/jpeg';
        
        // 转换为base64
        try {
          const compressedBase64 = canvas.toDataURL(mimeType, isPNG ? undefined : quality);
          // 移除data URL前缀，只保留base64数据
          const base64Data = compressedBase64.split(',')[1];
          resolve(base64Data);
        } catch (error: any) {
          reject(new Error('图片压缩失败'));
        }
      };
      
      img.onerror = () => {
        reject(new Error('图片加载失败'));
      };
      
      // 读取文件
      const reader = new FileReader();
      reader.onload = (e) => {
        img.src = e.target?.result as string;
      };
      reader.onerror = () => {
        reject(new Error('读取文件失败'));
      };
      reader.readAsDataURL(file);
    });
  }

  /**
   * 将base64数据转换为Blob对象
   * @param base64Data base64编码的数据
   * @param file 原始文件对象，用于确定MIME类型
   * @returns 转换后的Blob对象
   */
  static base64ToBlob(base64Data: string, file: File): Blob {
    // 将base64转换为Blob
    const byteCharacters = atob(base64Data);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    
    // 根据文件类型确定MIME类型
    const isPNG = file.type.toLowerCase().includes('png');
    const mimeType = isPNG ? 'image/png' : 'image/jpeg';
    
    return new Blob([byteArray], { type: mimeType });
  }

  /**
   * 将Blob保存为临时文件
   * @param blob 要保存的Blob对象
   * @param fileName 文件名
   * @returns 临时文件的路径
   */
  static async saveBlobToTempFile(blob: Blob, fileName: string): Promise<string> {
    return new Promise(async (resolve, reject) => {
      const reader = new FileReader();
      reader.onload = async () => {
        try {
          const arrayBuffer = reader.result as ArrayBuffer;
          const uint8Array = new Uint8Array(arrayBuffer);
          
          const tempDirPath = await tempDir();
          const filePath = await join(tempDirPath, fileName);
          
          await writeFile(filePath, uint8Array);
          
          resolve(filePath);
        } catch (error) {
          reject(error);
        }
      };
      reader.onerror = () => reject(new Error('读取Blob失败'));
      reader.readAsArrayBuffer(blob);
    });
  }

  /**
   * 处理图片并创建临时文件路径（综合方法）
   * @param file 要处理的图片文件
   * @returns 处理后的临时文件路径
   */
  static async processImageAndCreateTempFile(file: File): Promise<string> {
    // 检查文件大小
    await ImageProcessor.checkFileSize(file);
    
    // 压缩图片
    const compressedBase64 = await ImageProcessor.compressImage(file);
    
    // 将base64转换为Blob
    const blob = ImageProcessor.base64ToBlob(compressedBase64, file);
    
    // 创建临时文件路径
    const tempFileName = `temp_${Date.now()}_${file.name}`;
    const tempFilePath = await ImageProcessor.saveBlobToTempFile(blob, tempFileName);
    
    return tempFilePath;
  }
}

/**
 * Vue组合式函数，提供图片处理功能
 */
export function useImageProcessor() {
  return {
    processImageAndCreateTempFile: ImageProcessor.processImageAndCreateTempFile,
    checkFileSize: ImageProcessor.checkFileSize,
    compressImage: ImageProcessor.compressImage,
    base64ToBlob: ImageProcessor.base64ToBlob,
    saveBlobToTempFile: ImageProcessor.saveBlobToTempFile
  };
}